package dao;

import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;

import org.apache.log4j.Logger;

import bean.CompactDisc;
import bean.Producer;
import bean.TypeCD;

import com.google.gson.Gson;

import database.PersistenceUtil;

public class CompactDiscDao {
	private static final Logger LOGGER = Logger.getLogger(CompactDiscDao.class);
	
	public static CompactDisc getCompactDisc(String name) throws Exception {
		EntityManager conn = PersistenceUtil.getEntityManager();
		try {
			List<CompactDisc> disks = conn.createNamedQuery("CompactDisc.findbyName", CompactDisc.class).setParameter("name", name).getResultList();
			if (disks.isEmpty()) {
				return null;
			}
			return disks.get(0);
		} catch (Exception e) {
			LOGGER.error("Error while getting cd with name "+ name +" \n" + e.getMessage());
			throw e;
		} finally{
				conn.close();
		}
	}
	
	public static CompactDisc getCompactDisc(Long id) throws Exception {
		EntityManager conn = PersistenceUtil.getEntityManager();
		try {
			List<CompactDisc> disks = conn.createNamedQuery("CompactDisc.findbyId", CompactDisc.class).setParameter("id", id).getResultList();
			if (disks.isEmpty()) {
				return null;
			}
			return disks.get(0);
		} catch (Exception e) {
			LOGGER.error("Error while getting cd with id "+ id +" \n" + e.getMessage());
			throw e;
		} finally{
				conn.close();
		}
	}
	
	
	public static List<CompactDisc> getCompactDiscs() throws Exception {
		EntityManager conn = PersistenceUtil.getEntityManager();
		try {
			List<CompactDisc> disks = conn.createNamedQuery("CompactDisc.findAll", CompactDisc.class).getResultList();
			if (disks.isEmpty()) {
				return null;
			}
			return disks;
		} catch (Exception e) {
			LOGGER.error("Error while getting cds \n" + e.getMessage());
			throw e;
		} finally{
				conn.close();
		}
	}
	
	public static String insertCompactDisc(String name, String producerName, String type, Date data) throws Exception {
		EntityManager conn = PersistenceUtil.getEntityManager();
		try {
			conn.getTransaction().begin();
			Producer producer = ProducerDao.findProducer(producerName);
			if (producer == null) {
				producer = new Producer(producerName);
				conn.persist(producer);
			}
			TypeCD cdType = TypeCDDao.findTypeCD(type);
			if (cdType == null) {
				cdType = new TypeCD(type);
				conn.persist(cdType);
			}
			
			CompactDisc cd = new CompactDisc(name, producer, cdType);
			cd.setInsertDate(new Date());
			cd.setAquisitionDate(data);
			conn.persist(cd);
			conn.getTransaction().commit();
			LOGGER.info("CD created : cd=" + name + " ,producer=" + producerName
					+ " ,type= " + type);
			String cdInserted = new Gson().toJson(cd);
			return cdInserted;
		} catch (Exception e) {
			String error = "Error while creating cd : cd=" + name
					+ " ,producer=" + producerName + " ,type= " + type + "\n" + e.getMessage();
			LOGGER.error(error);
			conn.getTransaction().rollback();
			throw e;
		} finally {
			conn.close();
		}
	}

	public static String updateCompactDisc(Long id, String name, String producerName, String type, Date data) throws Exception {
		EntityManager conn = PersistenceUtil.getEntityManager();
		try {
			conn.getTransaction().begin();
			CompactDisc cd = getCompactDisc(id);
			if (cd == null) {
				String error = "CD with id " + id + " not found";
				LOGGER.error(error);
				return error;
			}
			
			Producer producer = ProducerDao.findProducer(producerName);
			if (producer == null) {
				producer = new Producer(producerName);
				conn.persist(producer);
			}
			TypeCD cdType = TypeCDDao.findTypeCD(type);
			if (cdType == null) {
				cdType = new TypeCD(type);
				conn.persist(cdType);
			}
			
			cd.setAquisitionDate(data);
			cd.setProducer(producer);
			cd.setCdType(cdType);
			cd.setName(name);
			conn.merge(cd);
			conn.getTransaction().commit();
			LOGGER.info("CD updated : cd=" + name + " ,producer=" + producerName
					+ " ,type= " + type);
			String cdInserted = new Gson().toJson(cd);
			return cdInserted;
		} catch (Exception e) {
			String error = "Error while updating cd : cd=" + name
					+ " ,producer=" + producerName + " ,type= " + type + "\n" + e.getMessage();
			LOGGER.error(error);
			conn.getTransaction().rollback();
			throw e;
		} finally {
			conn.close();
		}
	}
	
	public static String deleteCompactDiscs(List<Long> cdIds) throws Exception {
		EntityManager conn = PersistenceUtil.getEntityManager();
		try {
			conn.getTransaction().begin();
			for (Long id : cdIds) {
				CompactDisc cd = conn.createNamedQuery("CompactDisc.findbyId", CompactDisc.class).setParameter("id", id).getSingleResult();
				conn.remove(cd);
			}
			conn.getTransaction().commit();
			return "OK";
		} catch (Exception e) {
			LOGGER.error("Error while deleting cds \n" + e.getMessage());
			throw e;
		} finally{
			conn.close();
		}
	}
}
